package tech.summerly.weather.util

import android.arch.lifecycle.LifecycleOwner
import android.arch.lifecycle.LiveData
import android.content.Context
import android.graphics.Point
import android.os.Bundle
import android.support.annotation.LayoutRes
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentTransaction
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
import com.google.android.exoplayer2.ExoPlaybackException
import com.google.android.exoplayer2.PlaybackParameters
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.Timeline
import com.google.android.exoplayer2.source.TrackGroupArray
import com.google.android.exoplayer2.trackselection.TrackSelectionArray
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
import tech.summerly.weather.AppContext
import java.util.*
import kotlin.reflect.KProperty

/**
 * author : summerly
 * e-mail : yangbinyhbn@gmail.com
 * time   : 2017/7/22
 * desc   : ItemViewBinder 的 Kotlin封装类
 */
open class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    companion object {
        operator fun invoke(@LayoutRes layoutId: Int, parent: ViewGroup, inflater: LayoutInflater): ViewHolder {
            return ViewHolder(inflater.inflate(layoutId, parent, false))
        }

        fun createView(@LayoutRes layoutId: Int, parent: ViewGroup): View {
            val inflater = LayoutInflater.from(parent.context)
            return inflater.inflate(layoutId, parent, false)
        }
    }
}


fun getRealScreenSize(context: Context = AppContext.instance): Point {
    val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    val display = windowManager.defaultDisplay
    val point = Point()
    display.getRealSize(point)
    return point
}

fun getAppUsableScreenSize(context: Context = AppContext.instance): Point {
    val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
    val display = windowManager.defaultDisplay
    return Point().also {
        display.getSize(it)
    }
}

fun getNavigationBarHeight(context: Context = AppContext.instance): Int {
    val usable = getAppUsableScreenSize(context)
    val real = getRealScreenSize(context)

    //navigation bar on the right
    if (usable.x < real.x) {
        return usable.x - real.x
    }
    if (usable.y < real.y) {
        return real.y - usable.y
    }
    return 0
}

fun toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) = Toast.makeText(AppContext.instance, message, duration).show()

fun today(): Calendar {
    val today = Calendar.getInstance()
    today.time = Date(System.currentTimeMillis())
    return today
}


fun FragmentManager.inTransaction(transaction: FragmentTransaction.() -> Unit) {
    val fragmentTransaction = beginTransaction()
    try {
        transaction(fragmentTransaction)
    } finally {
        fragmentTransaction.commit()
    }
}

/**
 * 关闭自己
 */
fun Fragment.closeSelf() {
    activity?.supportFragmentManager?.apply {
        val transaction = beginTransaction()
        transaction.remove(this@closeSelf)
        transaction.commit()
    }
}

fun View.setOnclickListenerSafely(listener: suspend (View) -> Unit) {
    setOnClickListener {
        launch(UI) {
            isClickable = false
            listener.invoke(it)
            isClickable = true
        }
    }
}

fun <T : Any> LiveData<T>.observeFilterNull(lifecycleOwner: LifecycleOwner, observer: (T) -> Unit) {
    observe(lifecycleOwner, android.arch.lifecycle.Observer<T> {
        it?.let(observer)
    })
}

fun <T : Any> LiveData<T>.observe(lifecycleOwner: LifecycleOwner, observer: (T?) -> Unit) {
    observe(lifecycleOwner, android.arch.lifecycle.Observer<T> {
        observer(it)
    })
}


object EmptyPlayerEventListener : Player.EventListener {
    override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) {
    }

    override fun onSeekProcessed() {
    }

    override fun onTracksChanged(trackGroups: TrackGroupArray, trackSelections: TrackSelectionArray) {
    }

    override fun onPlayerError(error: ExoPlaybackException?) {
    }

    override fun onLoadingChanged(isLoading: Boolean) {
    }

    override fun onPositionDiscontinuity(reason: Int) {
    }

    override fun onRepeatModeChanged(repeatMode: Int) {
    }

    override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
    }

    override fun onTimelineChanged(timeline: Timeline, manifest: Any?, reason: Int) {
    }

    override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
    }

}

/**
 * bundle delegate
 */
inline operator fun <reified T> Bundle?.getValue(thisRef: Any?, kProperty: KProperty<*>): T {
    val key = kProperty.name
    if (thisRef is Fragment) {
        return thisRef.arguments?.get(key) as T
    }
    return this?.get(key) as T
}